/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007 - 2008 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/

package com.genia.toolbox.web.gwt.basics.client.widget;

import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.SourcesTabEvents;
import com.google.gwt.user.client.ui.TabBar;
import com.google.gwt.user.client.ui.TabListener;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * a {@link TabPanel} that only attach its widgets when the tab is shown for the
 * first time.
 */
public class LazyTabPanel
    extends Composite
{
  /**
   * a {@link FlowPanel} that will display its only widget only when asked for.
   */
  private class LazyFlowPanel
      extends FlowPanel
  {
    /**
     * the widget to display when asked.
     */
    private Widget widgetToDisplay;



    /**
     * constructor.
     * 
     * @param widgetToDisplay
     *          the widget to display when asked.
     */
    public LazyFlowPanel(Widget widgetToDisplay)
    {
      this.widgetToDisplay = widgetToDisplay;
    }



    /**
     * display the keeped widget if it is not yet displayed.
     */
    public void initPanel()
    {
      if (widgetToDisplay != null) {
        add(widgetToDisplay);
        widgetToDisplay = null;
      }
    }
  }



  /**
   * the {@link TabPanel} to display.
   */
  private final TabPanel tabPanel = new TabPanel();

  /**
   * constructor.
   */
  public LazyTabPanel()
  {
    tabPanel.addTabListener(new TabListener()
    {

      /**
       * Fired just before a tab is selected.
       * 
       * @param sender
       *          the {@link com.google.gwt.user.client.ui.TabBar} or
       *          {@link TabPanel} whose tab was selected.
       * @param tabIndex
       *          the index of the tab about to be selected
       * @return <code>false</code> to disallow the selection. If any listener
       *         returns false, then the selection will be disallowed.
       */
      public boolean onBeforeTabSelected(SourcesTabEvents sender, int tabIndex)
      {
        ((LazyFlowPanel) tabPanel.getWidget(tabIndex)).initPanel();
        return true;
      }



      /**
       * Fired when a tab is selected.
       * 
       * @param sender
       *          the {@link com.google.gwt.user.client.ui.TabBar} or
       *          {@link TabPanel} whose tab was selected
       * @param tabIndex
       *          the index of the tab that was selected
       */
      public void onTabSelected(SourcesTabEvents sender, int tabIndex)
      {
        // Do nothing.
      }

    });
    initWidget(tabPanel);
  }



  /**
   * Adds a widget to the tab panel. If the Widget is already attached to the
   * TabPanel, it will be moved to the right-most index.
   * 
   * @param w
   *          the widget to be added
   * @param tabWidget
   *          the widget to be shown in the tab
   * @see com.google.gwt.user.client.ui.TabPanel#add(com.google.gwt.user.client.ui.Widget,
   *      com.google.gwt.user.client.ui.Widget)
   */
  public void add(Widget w, Widget tabWidget)
  {
    tabPanel.add(new LazyFlowPanel(w), tabWidget);
  }



  /**
   * add a {@link TabListener} that will be called each time a new tab is
   * selected.
   * 
   * @param listener
   *          the {@link TabListener} to add
   * @see com.google.gwt.user.client.ui.TabPanel#addTabListener(com.google.gwt.user.client.ui.TabListener)
   */
  public void addTabListener(TabListener listener)
  {
    tabPanel.addTabListener(listener);
  }



  /**
   * Gets the tab bar within this tab panel. Adding or removing tabs from from
   * the TabBar is not supported and will throw UnsupportedOperationExceptions.
   * 
   * @return the tab bar
   * @see com.google.gwt.user.client.ui.TabPanel#getTabBar()
   */
  public TabBar getTabBar()
  {
    return tabPanel.getTabBar();
  }



  /**
   * Programmatically selects the specified tab.
   * 
   * @param index
   *          the index of the tab to be selected
   * @see com.google.gwt.user.client.ui.TabPanel#selectTab(int)
   */
  public void selectTab(int index)
  {
    tabPanel.selectTab(index);
  }
}
